// CCSetup.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "resource.h"
#include "trace.h"

const TCHAR SETUP_FILE_NAME[] = _T("Setup.exe");
const TCHAR MSI_FILE_NAME[] = _T("CreativeCommonsOffice2007Addins.msi");

// Purpose:
//		Extract binary file that is embedded as part of the resources and save to temp path
// Inputs: 
//		ResourceID of type RT_RCDATA
//		Filename to saveas
BOOL SaveEmbeddedBinary(WORD wResourceId, const TCHAR * lpszFileName)
{
    BOOL bStatus = FALSE;
	HGLOBAL hglobal = NULL;
	HRSRC hrsrc = NULL;
	LPVOID lpv = NULL;
	DWORD dwFileSize = 0;
	HANDLE hFile = NULL;
	DWORD dwCount = 0;
    
	hrsrc = FindResource(NULL, MAKEINTRESOURCE(wResourceId), RT_RCDATA);
	if(hrsrc)
	{
		hglobal = LoadResource(NULL, hrsrc);

		if(hglobal)
		{
			lpv = LockResource(hglobal);
			if(lpv)
			{
				dwFileSize = SizeofResource(NULL, hrsrc);

				hFile = CreateFile(
					lpszFileName,
					GENERIC_READ | GENERIC_WRITE,
					0,
					NULL,
					CREATE_ALWAYS,
					FILE_ATTRIBUTE_NORMAL,
					NULL
					);

				if(hFile != NULL && hFile != INVALID_HANDLE_VALUE )
				{
					bStatus = WriteFile(hFile, lpv, dwFileSize, &dwCount, NULL);
					CloseHandle(hFile);
				}
			}
		}
	}

    return bStatus;
}

// Purpose:
//		Extract setup.exe and .msi that are embedded as part of the resources and launch setup.exe
// Inputs: 
//		None
BOOL SelfExtractAndInstall()
{
	CTrace::WriteLine(_T("Inside SelfExtractAndInstall()"));
    BOOL bStatus = FALSE;
	LPTSTR szPath = NULL;
    size_t nFileNameSize = 0;
    size_t nFileFullPathSize = 0;
    LPTSTR szSetupFileName = NULL;
	LPTSTR szMsiFileName = NULL;
	HRESULT hr = S_OK;

	//get temp path
	size_t nTempPathSize = GetTempPath(0, szPath);
    szPath = new TCHAR[nTempPathSize+1];
    nTempPathSize = GetTempPath(nTempPathSize+1, szPath);

	hr = StringCchLength(SETUP_FILE_NAME, STRSAFE_MAX_CCH, &nFileNameSize);
	if(SUCCEEDED(hr))
	{
		nFileFullPathSize = nTempPathSize + nFileNameSize + 1;
		szSetupFileName = new TCHAR [nFileFullPathSize];
		hr = StringCchPrintf(szSetupFileName, nFileFullPathSize, _T("%s%s"), szPath, SETUP_FILE_NAME);
		if(SUCCEEDED(hr))
		{
			// get setup.exe from resources
    		bStatus = SaveEmbeddedBinary(IDR_SETUP_EXE, szSetupFileName);
		}
	}

	if(!bStatus)
	{
		CTrace::WriteLine(_T("Unable to extract and save Setup.exe"));
	}
	else
	{
		bStatus = FALSE;
		hr = StringCchLength(MSI_FILE_NAME, STRSAFE_MAX_CCH, &nFileNameSize);
		if(SUCCEEDED(hr))
		{
			nFileFullPathSize = nTempPathSize + nFileNameSize + 1;
			szMsiFileName = new TCHAR [nFileFullPathSize];
			hr = StringCchPrintf(szMsiFileName, nFileFullPathSize, _T("%s%s"), szPath, MSI_FILE_NAME);
			if(SUCCEEDED(hr))
			{
				// get msi from resources
				bStatus = SaveEmbeddedBinary(IDR_MSI, szMsiFileName);
			}
		}

		if(!bStatus)
		{
			CTrace::WriteLine(_T("Unable to extract and save msi"));
		}
		else
		{
			// launch setup.exe
			STARTUPINFO si;
			ZeroMemory(&si, sizeof(si));
			si.cb = sizeof(si);

			PROCESS_INFORMATION pi;
			ZeroMemory(&pi, sizeof(pi));

			bStatus = CreateProcess(
							szSetupFileName, 
							NULL, 
							NULL, 
							NULL, 
							TRUE, 
							0, 
							NULL, 
							szPath, 
							&si, 
							&pi);
			if(!bStatus)
			{
				CTrace::WriteLine(_T("Unable to launch setp.exe"));
			}
		}
	}

	//free up the allocated memory
	delete [] szSetupFileName;
    delete [] szMsiFileName;
    delete [] szPath;

    return bStatus;
}

int _tmain(int argc, _TCHAR* argv[])
{
	CTrace::WriteLine(_T("Inside main function"));
	return SelfExtractAndInstall();
}

